﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

using Microsoft.Practices.Unity;

using ERPStore.Web.Routing;
using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Html
{
	/// <summary>
	/// 
	/// </summary>
	public static class SeoExtensions
	{
		/// <summary>
		/// Balise méta de description de la page
		/// doit etre comprise entre 25 et 150 caractères
		/// </summary>
		/// <param name="helper">The helper.</param>
		/// <param name="description">The description.</param>
		/// <returns></returns>
		public static MvcHtmlString MetaDescription(this HtmlHelper helper, string description)
		{
			if (description == null || description.Length < 25)
			{
				description += " : " + ERPStore.GlobalConfiguration.Configuration.Settings.SiteName;
			}
			return new MvcHtmlString(string.Format("<meta name=\"description\" content=\"{0}\" />", description.Replace("\"", "''").EllipsisAt(150)));
		}

		public static MvcHtmlString MetaKeywords(this HtmlHelper helper, string keywords)
		{
			return new MvcHtmlString(string.Format("<meta name=\"keywords\" content=\"{0}\" />", keywords));
		}

		/// <summary>
		/// Titre de la page 
		/// doit etre compris entre 5 et 65 caractères
		/// </summary>
		/// <param name="helper">The helper.</param>
		/// <param name="title">The title.</param>
		/// <returns></returns>
		public static MvcHtmlString PageTitle(this HtmlHelper helper, string title)
		{
			if (title == null)
			{
				title = string.Empty;
			}
			return new MvcHtmlString(string.Format("<title>{0}</title>", title.Trim()));
		}

		public static MvcHtmlString PageTitle(this HtmlHelper helper, ERPStore.Models.Product product)
		{
			if (!product.PageTitle.IsNullOrTrimmedEmpty())
			{
				return helper.PageTitle(product.PageTitle);
			}
			return helper.PageTitle(product.Title);
		}

		public static MvcHtmlString MetaInformations(this HtmlHelper helper)
		{
			var currentRoute = helper.ViewContext.RouteData.Route as ERPStoreRoute;
			var result = new StringBuilder();
			if (currentRoute == null)
			{
                var logger = DependencyResolver.Current.GetService<ERPStore.Logging.ILogger>();
				logger.Warn("No metainformations for currentRoute {0}", helper.ViewContext.HttpContext.Request.RawUrl);
			}
			else
			{
				var controller = currentRoute.Defaults["Controller"];
				var action = currentRoute.Defaults["Action"];
				var language = currentRoute.Defaults["Language"];
				var name = currentRoute.Name;
				var uniqueName = string.Format("{0}/{1}", controller, name);
				string categoryName = null;
				string brandName = null;

				var sort = string.Empty;
				var sortBy = helper.ViewContext.HttpContext.Request["sortby"];
				if (sortBy != null)
				{
					sort = " trié par ";
					switch (sortBy.ToLower())
					{
						case "title":
							sort += "nom";
							break;
						case "saleprice":
							sort += "prix";
							break;
						case "stats.ordercount":
							sort += "meilleures ventes";
							break;
					}
					if (helper.ViewContext.HttpContext.Request["sortdirection"] == "desc")
					{
						sort += " dans l'ordre décroissant ";
					}
				}

				var stock = string.Empty;
				if (helper.ViewContext.HttpContext.Request["hasstock"] == "1")
				{
					stock = " en stock ";
				}

				switch (uniqueName.ToLower())
				{
					case "catalog/brands":
					case "catalog/brandlist" : // Liste des marques
						result.Append(helper.PageTitle(string.Format("Les marques proposées par {0}", ERPStore.GlobalConfiguration.Configuration.Settings.SiteName)));
						var brands = helper.ViewData.Model as IList<ERPStore.Models.Brand>;
						var brandList = brands.OrderByDescending(i => i.ProductCount)
												.Take(10)
												.Select(i => i.Name)
												.JoinString(",");

						result.Append(helper.MetaDescription(string.Format("Les marques proposées par {0}, {1}",ERPStore.GlobalConfiguration.Configuration.Settings.SiteName, brandList)));
						break;
					case "catalog/productcategories" :
					case "catalog/categorylist": // Liste des categories
						result.Append(helper.PageTitle(string.Format("Les catégories de produit proposées par {0}", ERPStore.GlobalConfiguration.Configuration.Settings.SiteName)));
						var categories = helper.ViewData.Model as IList<ERPStore.Models.ProductCategory>;
						var categoryList = categories.Take(10).Select(i => i.Name).JoinString(",");
						result.Append(helper.MetaDescription(string.Format("Les catégories proposées par {0}, {1}", ERPStore.GlobalConfiguration.Configuration.Settings.SiteName, categoryList)));
						break;
					case "catalog/productbycategory": 
					case "catalog/category":
						var productByCategorylist = helper.ViewData.Model as ERPStore.Models.ProductList;
						if (productByCategorylist.Brand != null)
						{
							brandName = string.Format(" marque {0}", productByCategorylist.Brand.Name);
						}
						var categoryPager = string.Empty;
						if (productByCategorylist.PageIndex > 1)
						{
							categoryPager = string.Format(", page {0}/{1}", productByCategorylist.PageIndex, productByCategorylist.GetPageCount());
						}
						result.Append(helper.PageTitle(string.Format("{0}{1}{2}{3}{4}", productByCategorylist.Category.PageTitle, stock, brandName, sort, categoryPager)));
						if (!productByCategorylist.Category.PageDescription.IsNullOrTrimmedEmpty())
						{
							result.Append(helper.MetaDescription(string.Format("{0}{1}{2}{3}{4}", productByCategorylist.Category.PageDescription, stock, brandName, sort, categoryPager)));
						}
						else
						{
							result.Append(helper.MetaDescription(string.Format("Les produits de la categorie {0}{1}{2}", productByCategorylist.Category.Name, brandName, categoryPager)));
						}
						break;
					case "catalog/productbybrand":
					case "catalog/brand":
						var productByBrandList = helper.ViewData.Model as ERPStore.Models.ProductList;
						if (productByBrandList.Category != null)
						{
							categoryName = string.Format(" categorie {0}", productByBrandList.Category.Name);
						}
						var brandPager = string.Empty;
						if (productByBrandList.PageIndex > 1)
						{
							brandPager = string.Format(", page {0}/{1}", productByBrandList.PageIndex, productByBrandList.GetPageCount());
						}

						result.Append(helper.PageTitle(string.Format("{0}{1}{2}{3}{4}", productByBrandList.Brand.PageTitle, stock, categoryName, sort, brandPager)));
						if (!productByBrandList.Brand.PageDescription.IsNullOrTrimmedEmpty())
						{
							result.Append(helper.MetaDescription(string.Format("{0}{1}{2}{3}{4}", productByBrandList.Brand.PageDescription, stock, categoryName, sort, brandPager)));
						}
						else
						{
							result.Append(helper.MetaDescription(string.Format("Les produits de la marque {0}{1}{2}", productByBrandList.Brand.Name, categoryName, brandPager)));
						}
						//if (!productByBrandList.Brand.Keywords.IsNullOrTrimmedEmpty())
						//{
						//    result.Append(helper.MetaKeywords(productByBrandList.Brand.Keywords));
						//}
						break;
					case "catalog/product" : // Fiche produit
						var product = helper.ViewData.Model as ERPStore.Models.Product;
						result.Append(helper.PageTitle(product));
						if (!product.PageDescription.IsNullOrTrimmedEmpty())
						{
							result.Append(helper.MetaDescription(product.PageDescription));
						}
						else if (!product.ShortDescription.IsNullOrTrimmedEmpty())
						{
							result.Append(helper.MetaDescription(product.ShortDescription));
						}
						else
						{
							result.Append(helper.MetaDescription(product.Title));
						}
						break;
					default:
						break;
				}
			}
			return new MvcHtmlString(result.ToString());
		}

		public static string Tracker(this HtmlHelper helper)
		{
			var currentRoute = helper.ViewContext.RouteData.Route as System.Web.Routing.Route;
			var result = new StringBuilder();
			if (currentRoute == null)
			{
				return null;
			}
			var controller = currentRoute.Defaults["Controller"];
			var action = currentRoute.Defaults["Action"];
			var language = currentRoute.Defaults["Language"];
			var name = currentRoute.Defaults["Name"];
			var uniqueName = string.Format("{0}/{1}", controller, name);
			switch (uniqueName.ToLower())
			{
				case "quotecart/quotesent":

					break;
			}

			return result.ToString();
		}

		public static MvcHtmlString MetaInformations(this HtmlHelper helper, ERPStore.Models.Product product)
		{
			var sb = new StringBuilder();
			sb.Append(helper.PageTitle(product));
			if (!product.PageDescription.IsNullOrTrimmedEmpty())
			{
				sb.Append(helper.MetaDescription(product.PageDescription));
			}
			else if (product.ShortDescription.IsNullOrTrimmedEmpty())
			{
				sb.Append(helper.MetaDescription(product.ShortDescription));
			}
			else
			{
				sb.Append(helper.MetaDescription(product.Title));
			}
			//if (!product.Keywords.IsNullOrTrimmedEmpty())
			//{
			//    sb.Append(helper.MetaKeywords(product.Keywords));
			//}
			//else
			//{
			//    sb.Append(helper.MetaKeywords(product.Title));
			//}
			return new MvcHtmlString(sb.ToString());
		}

		public static MvcHtmlString Canonical(this UrlHelper helper)
		{
			var result = "<link rel=\"canonical\" href=\"http://{0}{1}\"/>";
			// var language = helper.GetCurrentLanguage();
			var host = ERPStore.GlobalConfiguration.Configuration.Settings.DefaultUrl;
			var url = helper.RequestContext.HttpContext.Request.RawUrl;
			url = url.RemoveParameter("from");
			return new MvcHtmlString(string.Format(result, host, url));
		}

		public static MvcHtmlString Canonical(this UrlHelper helper, string RouteName)
		{
			var result = "<link rel=\"canonical\" href=\"http://{0}{1}\"/>";
			// var language = helper.GetCurrentLanguage();
			var host = helper.RequestContext.HttpContext.Request.Url.Host;
			var url = helper.RouteERPStoreUrl(RouteName, null);
			return new MvcHtmlString(string.Format(result, host, url));
		}

		public static string ReplacePlaceHolder(this System.Web.Mvc.HtmlHelper helper, string input)
		{
			if (input == null)
			{
				return null;
			}
			var brand = helper.ViewContext.RequestContext.HttpContext.Request[ERPStore.GlobalConfiguration.Configuration.Settings.Catalog.BrandParameterName];
			input = System.Text.RegularExpressions.Regex.Replace(input, @"\{brand\}", brand ?? string.Empty);

			var category = helper.ViewContext.RequestContext.HttpContext.Request[ERPStore.GlobalConfiguration.Configuration.Settings.Catalog.ProductCategoryParameterName];
			if (category != null)
			{
				var catalogService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.ICatalogService>();
				var c = catalogService.GetCategoryByCode(category);
				if (c != null)
				{
					category = c.Name;
				}
			}
			input = System.Text.RegularExpressions.Regex.Replace(input, @"\{category\}", category ?? string.Empty);

			var stock = helper.ViewContext.RequestContext.HttpContext.Request[ERPStore.GlobalConfiguration.Configuration.Settings.Catalog.HasStockFilterParameterName];
			if (stock != null)
			{
				if (stock == "1")
				{
					stock = " disponible en stock";
				}
			}
			input = System.Text.RegularExpressions.Regex.Replace(input, @"\{stock\}", stock ?? string.Empty);

			var sort = helper.ViewContext.RequestContext.HttpContext.Request[ERPStore.GlobalConfiguration.Configuration.Settings.Catalog.PageSortParameterName];
			if (sort != null)
			{
				switch (sort.ToLower())
				{
					case "title":
						sort = " trié par nom";
						break;
					case "saleprice":
						sort = " trié par prix";
						break;
					case "stats.ordercount":
						sort = " trié par meilleures ventes";
						break;
				}
				var sortDirection = helper.ViewContext.RequestContext.HttpContext.Request[ERPStore.GlobalConfiguration.Configuration.Settings.Catalog.PageSortDirectionParameterName];
				if ("desc".Equals(sortDirection, StringComparison.InvariantCultureIgnoreCase ))
				{
					sort = sort + " dans l'ordre décroissant";
				}
			}

			input = System.Text.RegularExpressions.Regex.Replace(input, @"\{sort\}", sort ?? string.Empty);
			return input;
		}

	}
}
